package org.compiere.process;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import org.adempiere.exceptions.DBException;
import org.apache.commons.net.ntp.TimeStamp;
import org.compiere.apps.ADialog;
import org.compiere.model.MPrepaidExpenses;
import org.compiere.model.MFactAcct;
import org.compiere.model.MJournal;
import org.compiere.model.MJournalBatch;
import org.compiere.model.MJournalLine;
import org.compiere.model.MPeriod;
import org.compiere.model.MSequence;
import org.compiere.model.X_A_Depreciation_Build;
import org.compiere.model.X_C_Period;
import org.compiere.model.X_GL_Category;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;

public class IncomeExpedentureCloseMonth extends SvrProcess{
	
	private int c_period_id;
	private int p_AD_Client_ID;
	private int p_AD_Org_ID;
	private int p_AD_User_ID;

	
	private String description = null;
	private String postingType = null;
	private String docStatus = null;
	private String documentNo = null;
	private String docAction = null;
	
	private int gl_category_id = 0;
	private int c_currency_id = 0;
	private int c_doctype_id = 0;
	
	private boolean processing = true;
	private boolean processed = true;
	private boolean isApproved = true;
	private boolean isActive = true;
	
	private Timestamp DateDoc = null;
	private Timestamp DateAcct = null;

	private int Revenue_Expence_Account = 0;
	private String Revenue = "";
	private String Expences = "";
	
	private CLogger Log = CLogger.getCLogger(IncomeExpedentureCloseMonth.class);
	
	@Override
	protected void prepare(){
		ProcessInfoParameter[] para = getParameter();
		for (int i = 0; i < para.length; i++)	{
			String name = para[i].getParameterName();
			if (para[i].getParameter() == null); 
			else if (para[i].getParameterName().compareTo("C_Period_ID") == 0)
			{
				c_period_id = Integer.parseInt(para[i].getParameter().toString());
			}
			else if (para[i].getParameterName().compareTo("Revenue_Expence_Account") == 0)
			{
				Revenue_Expence_Account = Integer.parseInt(para[i].getParameter().toString());
			}
			else if (para[i].getParameterName().compareTo("Revenue") == 0)
			{
				Revenue = para[i].getParameter().toString();
			}
			else if (para[i].getParameterName().compareTo("Expences") == 0)
			{
				Expences = para[i].getParameter().toString();
			}
			else
			{
				log.log(Level.SEVERE, "Unknown Parameter: " + name);
			}
		}
		
		//c_period_id = Integer.parseInt(para[0].getParameter().toString());
		p_AD_Client_ID = Env.getAD_Client_ID(getCtx());
		p_AD_Org_ID = Env.getAD_Org_ID(getCtx());
	 	p_AD_User_ID = Env.getAD_User_ID(getCtx());
	}
	
	/* (non-Javadoc)
	 * @see org.compiere.process.SvrProcess#doIt()
	 */
	@Override
	protected String doIt() throws Exception 
	{
		PreparedStatement pstmt = null;
		ResultSet rs = null;
/*
 * Add Ibraev E.A.
 * Created 21.09.2012
 * 
 * IEA {		
 */
		if (!CFPCloseMonth(c_period_id)) {
			return "Не закрыты расчеты будущих периодов";
		}
/* 
 * } IEA		
 */
		MPeriod period = new MPeriod(getCtx(), c_period_id, null);
		
		String clientCheck = " AND AD_Client_ID=" + getAD_Client_ID();
		
		StringBuffer sql = new StringBuffer();
				
		int accountID = -1;
		sql.setLength(0);		
		sql.append("SELECT account_id from adempiere.c_validcombination where c_validcombination_id = " + Revenue_Expence_Account);
		accountID = DB.getSQLValue(get_TrxName(), sql.toString());
		if(accountID < 0) return "Error account_id 1";		
		
		//Set C_DocType_ID
		sql.setLength(0);
        sql.append("SELECT C_DocType_ID FROM C_DocType"
		+ " WHERE Name='Closing of income and expenditure' AND DocBaseType='GLJ' AND isActive ='Y'"+clientCheck);        
        c_doctype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (c_doctype_id<0) return "Error DocTypeID";
		
		sql.setLength(0);		
		sql.append("SELECT GL_JournalBatch_ID FROM ADEMPIERE.GL_JournalBatch WHERE DOCSTATUS = 'CO' AND C_PERIOD_ID = " + String.valueOf(c_period_id)
				+ " AND C_DOCTYPE_ID = " + c_doctype_id);
		int batchID = DB.getSQLValue(get_TrxName(), sql.toString());
		
		ADialog dialog = new ADialog();
		
		if(batchID != -1)
		{
			if(dialog.ask(25, null, "Процесс \"Закрытие месяца. Доходы/Расходы\" уже был успешно завершен. Вы хотите запустить данный процесс повторно?"))
			{
				ReWriteBatch(batchID, period, accountID);
			}
			else
			{
				return "Операция отменена";
			}
		}
		
		//Set C_Currency_ID
		sql.setLength(0);
        sql.append("SELECT C_Currency_ID FROM C_AcctSchema "
		+ " WHERE isActive='Y'"+clientCheck);
        c_currency_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (c_currency_id<0) return "Error CurrencyID";
		
		//Set GL_Catecory_ID
		sql.setLength(0);
        sql.append("SELECT GL_Category_ID FROM GL_Category "
		+ " WHERE isActive='Y' AND CategoryType = '"+X_GL_Category.CATEGORYTYPE_Manual+"'"
        +" AND isDefault = 'Y'"+clientCheck);
        gl_category_id = DB.getSQLValue(get_TrxName(), sql.toString());
		if (gl_category_id<0) return "Error GL CategoryID";
		
		//Set Conversion Type
		sql.setLength(0);
		sql.append("SELECT C_ConversionType_ID FROM C_ConversionType "
		+ " WHERE isActive='Y' AND isDefault = 'Y'");
		//c_conversiontype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		int c_conversiontype_id = 114;		
		if (c_conversiontype_id<0) return "Error Conversion Type ID";
		
		//Set Conversion Type
		sql.setLength(0);
		sql.append("SELECT C_ConversionType_ID FROM C_ConversionType "
		+ " WHERE isActive='Y' AND isDefault = 'Y'");
		//c_conversiontype_id = DB.getSQLValue(get_TrxName(), sql.toString());
		c_conversiontype_id = 114;		
		if (c_conversiontype_id<0) return "Error Conversion Type ID";
				
		X_C_Period Period = new X_C_Period(getCtx(), c_period_id, null);		
		
		postingType = MJournalBatch.POSTINGTYPE_Actual;
		docStatus = MJournalBatch.STATUS_InProgress;
		docAction = MJournalBatch.ACTION_Prepare;
		
		MJournalBatch batch = new MJournalBatch(getCtx(), 0, null);		
		
		String dn = MSequence.getDocumentNo (p_AD_Client_ID, "gl_journalbatch", get_TrxName(), batch);
		if (dn == null)
			throw new DBException ("No DocumentNo");
		
		description = documentNo = dn;
		
		String documentNo2 = documentNo + "E";
		String documentNo3 = documentNo + "I";
		
		/*sql.setLength(0);
        sql.append("SELECT c_acctschema_id FROM GL_Category "
		+ " WHERE isActive='Y' "+clientCheck);
        int C_AcctSchema_ID = DB.getSQLValue(get_TrxName(), sql.toString());
		if (C_AcctSchema_ID < 0) return "Error C_AcctSchema_ID";
		*/
		
		int C_AcctSchema_ID = 1000000;
		
		batch.setClientOrg(p_AD_Client_ID, p_AD_Org_ID);
		batch.setDocumentNo(documentNo);
		batch.setDescription(description);
		batch.setPostingType(X_A_Depreciation_Build.POSTINGTYPE_Actual);
		batch.setGL_Category_ID(gl_category_id);
		batch.setDateDoc(Period.getEndDate());
		batch.setDateAcct(Period.getEndDate());
		batch.setC_Period_ID(c_period_id);
		batch.setC_Currency_ID(c_currency_id);
		batch.setControlAmt(BigDecimal.valueOf(0));
		batch.setC_DocType_ID(c_doctype_id);
		batch.setDocStatus(docStatus);
		batch.setDocAction(docAction);
		batch.setProcessing(true);
		batch.setProcessed(true);
		
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Batch Journal not saved - "+batch.getDocumentNo());
		}
		
		MJournal journal = new MJournal(batch);
		
		journal.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal.setIsActive(true);
		journal.setC_AcctSchema_ID(C_AcctSchema_ID);
		journal.setC_DocType_ID(batch.getC_DocType_ID());
		journal.setDocumentNo(documentNo3);
		journal.setDocStatus(docStatus);
		journal.setDocAction("--");
		journal.setIsApproved(true);
		journal.setIsPrinted(false);
		journal.setDescription(batch.getDescription());
		journal.setPostingType(batch.getPostingType());
		journal.setGL_Category_ID(batch.getGL_Category_ID());
		journal.setDateDoc(batch.getDateDoc());
		journal.setDateAcct(batch.getDateAcct());
		journal.setC_Period_ID(batch.getC_Period_ID());
		journal.setCurrencyRate(new BigDecimal(1));
		journal.setControlAmt(new BigDecimal(0));
		journal.setC_ConversionType_ID(c_conversiontype_id);
		journal.setProcessing(true);
		journal.setProcessed(true);
		journal.setPosted(true);
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		}
		
		MJournal journal2 = new MJournal(batch);
		
		journal2.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal2.setIsActive(true);
		journal2.setC_AcctSchema_ID(C_AcctSchema_ID);
		journal2.setC_DocType_ID(batch.getC_DocType_ID());
		journal2.setDocumentNo(documentNo2);
		journal2.setDocStatus(docStatus);
		journal2.setDocAction("--");
		journal2.setIsApproved(true);
		journal2.setIsPrinted(false);
		journal2.setDescription(batch.getDescription() + "2");
		journal2.setPostingType(batch.getPostingType());
		journal2.setGL_Category_ID(batch.getGL_Category_ID());
		journal2.setDateDoc(batch.getDateDoc());
		journal2.setDateAcct(batch.getDateAcct());
		journal2.setC_Period_ID(batch.getC_Period_ID());
		journal2.setCurrencyRate(new BigDecimal(1));
		journal2.setControlAmt(new BigDecimal(0));
		journal2.setC_ConversionType_ID(c_conversiontype_id);
		journal2.setProcessing(true);
		journal2.setProcessed(true);
		journal2.setPosted(true);
		if (!journal2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal2.getDocumentNo());
		}
			
		int validation1 = -1;
		int validation2 = -1;
		
		int accountID2 = -1;
		Double sumCredit = 0.0;
		Double sumDebit = 0.0;
		
		Double sumCredit2 = 0.0;
		Double sumDebit2 = 0.0;
		
		/*//Set GL_Catecory_ID
		sql.setLength(0);
		sql.append("SELECT c_elementvalue_id FROM c_elementvalue "
		+ " WHERE isActive='Y' AND value = '541000'" +clientCheck);
		accountID = DB.getSQLValue(get_TrxName(), sql.toString());
		if (accountID<0) return "Error C_ElementValue_ID2";
		*/
		
		//Set GL_Catecory_ID
		sql.setLength(0);
		sql.append("SELECT c_validcombination_id FROM c_validcombination "
		+ " WHERE isActive='Y' AND account_id = " + accountID + clientCheck);
		validation1 = DB.getSQLValue(get_TrxName(), sql.toString());
		if (validation1<0) return "Error C_ValidCombination_ID";
		
		double sumC1 = 0.0;
		double sumD2 = 0.0;
		
		double sumC3 = 0.0;
		double sumD4 = 0.0;
		
		sql.setLength(0);
		sql.append("SELECT ad_table_id FROM ad_table "
		+ " WHERE tablename='GL_Journal'");
		int ad_table2 = DB.getSQLValue(get_TrxName(), sql.toString());
		if (ad_table2<0) return "Error ad_table_id 2";
		
		String sqlAccounts = "select sum(amtsourcecr), sum(amtsourcedr), v.c_validcombination_id, e.value, e.c_elementvalue_id from adempiere.fact_acct f  "
				+ "inner join adempiere.c_elementvalue e on f.account_id = e.c_elementvalue_id "
				+ "inner join c_validcombination v on f.account_id = v.account_id "
				//+ "where f.c_period_id = " + c_period_id + " and (e.value like '" + Revenue + "' or e.value like '" + Expences + "') and v.ad_org_id = " + p_AD_Org_ID
				+ "where f.dateacct between '" + Period.getStartDate() + "' and '" + Period.getEndDate() + "' and (e.value like '" + Revenue + "' or e.value like '" + Expences + "') and v.ad_org_id = " + p_AD_Org_ID				
				+ " and v.c_bpartner_id is null"
				+ " group by v.c_validcombination_id, e.value, e.c_elementvalue_id";
		
		
		/*String sqlAccounts = "select sum(amtsourcecr)-sum(amtsourcedr) as \"6_value\", sum(amtsourcedr)-sum(amtsourcecr) as \"7_value\", v.c_validcombination_id, e.value, e.c_elementvalue_id from adempiere.fact_acct f  "
				+ "inner join adempiere.c_elementvalue e on f.account_id = e.c_elementvalue_id "
				+ "inner join c_validcombination v on f.account_id = v.account_id "
				+ "where f.c_period_id = " + c_period_id + " and (e.value like '" + Revenue + "' or e.value like '" + Expences + "') and v.ad_org_id = " + p_AD_Org_ID
				+ " group by v.c_validcombination_id, e.value, e.c_elementvalue_id";
		*/
		double totalCredit1 = 0.0;
		double totalDebit1 = 0.0;
		
		double totalCredit2 = 0.0;
		double totalDebit2 = 0.0;
		
		try
		{
			pstmt = DB.prepareStatement(sqlAccounts, get_TrxName());
			rs = pstmt.executeQuery();
			
			int lineCounter = 10;
//			int account_id = 1000055;
//			int validation_id = 0;			
			
			double difference7 = 0.0;
			
			while(rs.next())
			{
				sumDebit = rs.getBigDecimal(2).doubleValue();
				sumCredit = rs.getBigDecimal(1).doubleValue();
				difference7 = sumDebit - sumCredit;
				
				boolean isSeven = rs.getString("value").startsWith("7");
				
				if(isSeven)
					{
						MJournalLine line1 = new MJournalLine(journal);
						MJournalLine line2 = new MJournalLine(journal);
					
						line1.setAD_Org_ID(p_AD_Org_ID);
						line1.setLine(10);
//						line1.setAmtSourceDr(BigDecimal.valueOf(sumDebit));
						line1.setAmtSourceDr(BigDecimal.valueOf(difference7));
						line1.setAmtSourceCr(BigDecimal.valueOf(0));
						//line1.setCurr
						line1.setCurrency(journal.getC_Currency_ID(), journal.getC_ConversionType_ID(), new BigDecimal(1));
						line1.setDateAcct(journal.getDateAcct());
//						line1.setAmtAcctDr(BigDecimal.valueOf(sumDebit));
						line1.setAmtAcctDr(BigDecimal.valueOf(difference7));
						line1.setAmtAcctCr(BigDecimal.valueOf(0));
						line1.setC_ValidCombination_ID(Revenue_Expence_Account);
						line1.setProcessed(true);
						line1.setA_CreateAsset(false);
						line1.setA_Processed(false);
						
						if (!line1.save()) 
						{
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line1.getDescription());
						}
						
						MJournalLine.copyValues(line1, line2);
						
						line2.setAmtSourceDr(BigDecimal.valueOf(0));
						line2.setAmtSourceCr(BigDecimal.valueOf(difference7));
//						line2.setAmtSourceCr(BigDecimal.valueOf(sumDebit));				
						line2.setAmtAcctDr(BigDecimal.valueOf(0));
//						line2.setAmtAcctCr(BigDecimal.valueOf(sumDebit));
						line2.setAmtAcctCr(BigDecimal.valueOf(difference7));
						line2.setC_ValidCombination_ID(rs.getInt("c_validcombination_id"));
						if (!line2.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line2.getDescription());
						}
						
						MFactAcct fact = new MFactAcct(getCtx(), 0, get_TrxName());											
//						fact.setAmtSourceDr(BigDecimal.valueOf(sumDebit));
//						fact.setAmtSourceCr(BigDecimal.valueOf(sumCredit));
//						fact.setAmtAcctDr(BigDecimal.valueOf(sumDebit));

//						fact.setAmtAcctCr(BigDecimal.valueOf(sumCredit));
						//===
						fact.setAmtSourceDr(BigDecimal.valueOf(difference7));
						fact.setAmtAcctDr(BigDecimal.valueOf(difference7));
						fact.setAmtSourceCr(BigDecimal.valueOf(0));
						fact.setAmtAcctCr(BigDecimal.valueOf(0));
						//===
						fact.setRecord_ID(journal.get_ID());
						fact.setAD_Table_ID(224);
						fact.setAccount_ID(accountID);
						fact.setC_AcctSchema_ID(1000000);
						fact.setC_Period_ID(journal.getC_Period_ID());
						fact.setGL_Category_ID(journal.getGL_Category_ID());
						fact.setC_Currency_ID(journal.getC_Currency_ID());
						fact.setDateAcct(journal.getDateAcct());
						fact.setDateTrx(journal.getDateAcct());
						fact.setPostingType(MFactAcct.POSTINGTYPE_Actual);
						fact.setAD_Table_ID(ad_table2);	
						fact.setLine_ID(line1.get_ID());
						if (!fact.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact.getDescription());
						}
						MFactAcct fact2 = new MFactAcct(getCtx(), 0, get_TrxName());	
						MFactAcct.copyValues(fact, fact2);	
//						fact2.setAmtSourceCr(BigDecimal.valueOf(sumDebit));
//						fact2.setAmtSourceDr(BigDecimal.valueOf(sumCredit));
//						fact2.setAmtAcctCr(BigDecimal.valueOf(sumDebit));
						//----
						fact2.setAmtSourceCr(BigDecimal.valueOf(difference7));
						fact2.setAmtAcctCr(BigDecimal.valueOf(difference7));
						fact2.setAmtSourceDr(BigDecimal.valueOf(0));
						fact2.setAmtAcctDr(BigDecimal.valueOf(0));
						//----
//						fact2.setAmtAcctDr(BigDecimal.valueOf(sumCredit));
						fact2.setRecord_ID(journal.get_ID());
						fact2.setAD_Table_ID(ad_table2);
						fact2.setLine_ID(line2.get_ID());
						fact2.setAccount_ID(rs.getInt("c_elementvalue_id"));
						if (!fact2.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact2.getDescription());
						}
						totalCredit1 += sumCredit;
						totalDebit1 += sumDebit;
					}
					if(!isSeven)
					{
						MJournalLine line3 = new MJournalLine(journal2);
						MJournalLine line4 = new MJournalLine(journal2);
					
						line3.setAD_Org_ID(p_AD_Org_ID);
						line3.setLine(10);
						line3.setAmtSourceDr(BigDecimal.valueOf(sumCredit));
						line3.setAmtSourceCr(BigDecimal.valueOf(0));
						line3.setCurrency(journal.getC_Currency_ID(), journal.getC_ConversionType_ID(), new BigDecimal(1));
						line3.setDateAcct(journal.getDateAcct());
						line3.setAmtAcctDr(BigDecimal.valueOf(sumCredit));
						line3.setAmtAcctCr(BigDecimal.valueOf(0));
						line3.setC_ValidCombination_ID(rs.getInt("c_validcombination_id"));
						line3.setProcessed(true);
						line3.setA_CreateAsset(false);
						line3.setA_Processed(false);
						if (!line3.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line3.getDescription());
						}
						
						MJournalLine.copyValues(line3, line4);
						
						line4.setAmtSourceDr(BigDecimal.valueOf(0));
						line4.setAmtSourceCr(BigDecimal.valueOf(sumCredit));				
						line4.setAmtAcctDr(BigDecimal.valueOf(0));
						line4.setAmtAcctCr(BigDecimal.valueOf(sumCredit));
						line4.setC_ValidCombination_ID(Revenue_Expence_Account);
						if (!line4.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +line4.getDescription());
						}
												
						MFactAcct fact3 = new MFactAcct(getCtx(), 0, get_TrxName());					
						fact3.setAmtSourceDr(BigDecimal.valueOf(sumCredit));
//						fact3.setAmtSourceCr(BigDecimal.valueOf(sumDebit));
						fact3.setAmtAcctDr(BigDecimal.valueOf(sumCredit));
//						fact3.setAmtAcctCr(BigDecimal.valueOf(sumDebit));
						fact3.setRecord_ID(journal2.get_ID());
						fact3.setAccount_ID(rs.getInt("c_elementvalue_id"));
						fact3.setAD_Table_ID(ad_table2);
						fact3.setC_AcctSchema_ID(1000000);
						fact3.setC_Period_ID(journal.getC_Period_ID());
						fact3.setGL_Category_ID(journal2.getGL_Category_ID());
						fact3.setC_Currency_ID(journal2.getC_Currency_ID());
						fact3.setDateAcct(journal2.getDateAcct());
						fact3.setDateTrx(journal2.getDateAcct());
						fact3.setLine_ID(line3.get_ID());
						fact3.setPostingType(MFactAcct.POSTINGTYPE_Actual);					
						if (!fact3.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact3.getDescription());
						}
							
						MFactAcct fact4 = new MFactAcct(getCtx(), 0, get_TrxName());	
						MFactAcct.copyValues(fact3, fact4);
						fact4.setAmtSourceCr(BigDecimal.valueOf(sumCredit));
//						fact4.setAmtSourceDr(BigDecimal.valueOf(sumDebit));
						fact4.setAmtAcctCr(BigDecimal.valueOf(sumCredit));
//						fact4.setAmtAcctDr(BigDecimal.valueOf(sumDebit));
						
						//====
						fact4.setAmtSourceDr(BigDecimal.valueOf(0));
						fact4.setAmtAcctDr(BigDecimal.valueOf(0));
						//====
						
						fact4.setRecord_ID(journal2.get_ID());
						fact4.setAD_Table_ID(ad_table2);
						fact4.setLine_ID(line4.get_ID());
						fact4.setAccount_ID(accountID);
						if (!fact4.save()) {
							Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +fact4.getDescription());
						}
						
						totalCredit2 += sumCredit;
						totalDebit2 += sumDebit;
					}					
					lineCounter += 20;
			}
		}
		catch (Exception e)
		{
			
		}
		
		MathContext context = new MathContext(7);
	//	
/*		journal.setTotalCr(BigDecimal.valueOf(totalDebit1).round(context));
		journal.setTotalDr(BigDecimal.valueOf(totalDebit1).round(context));
		
		journal2.setTotalCr(BigDecimal.valueOf(totalCredit2).round(context));
		journal2.setTotalDr(BigDecimal.valueOf(totalCredit2).round(context));
		
		
		batch.setTotalCr(journal.getTotalDr().add(journal2.getTotalCr()));
		batch.setTotalDr(journal.getTotalDr().add(journal2.getTotalCr()));
*/

		journal.setTotalCr(BigDecimal.valueOf(totalDebit1).setScale(2, RoundingMode.HALF_UP));
		journal.setTotalDr(BigDecimal.valueOf(totalDebit1).setScale(2, RoundingMode.HALF_UP));
		
		journal2.setTotalCr(BigDecimal.valueOf(totalCredit2).setScale(2, RoundingMode.HALF_UP));
		journal2.setTotalDr(BigDecimal.valueOf(totalCredit2).setScale(2, RoundingMode.HALF_UP));
		
		
		batch.setTotalCr(journal.getTotalDr().add(journal2.getTotalCr()));
		batch.setTotalDr(journal.getTotalDr().add(journal2.getTotalCr()));

		
		//journal.setDocStatus(DOCSTATUS_COMPLETE)
		journal.setDocStatus("CO");
		journal2.setDocStatus(journal.getDocStatus());
		batch.setDocStatus("CO");
		
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +journal.getDocumentNo());
		}
		if (!journal2.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo()+ " " +journal2.getDocumentNo());
		}
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Line number one not saved - " + batch.getDocumentNo());
		}
		
		return "Процесс \"Закрытие месяца. Доходы/Расходы\" завершен успешно";
	}	
	
	private String ReWriteBatch(int batchID, MPeriod Period, int accountID2)
	{		
		String clientCheck = " AND AD_Client_ID=" + getAD_Client_ID();
	
		MJournalBatch batch = new MJournalBatch(getCtx(), batchID, null);
		
		MJournal[] journals = batch.getJournals(true);
		
		MJournalLine[] lines = journals[0].getLines(true);
		
		batch.setDocStatus(MJournalBatch.STATUS_InProgress);
		
		batch.setDocAction(MJournalBatch.ACTION_Complete);
		
		batch.save();
		
		String dn = MSequence.getDocumentNo (p_AD_Client_ID, "gl_journalbatch", get_TrxName(), batch);
		if (dn == null)
			throw new DBException ("No DocumentNo");
		
		documentNo = dn;
		
		MJournalBatch batch2 = new MJournalBatch(getCtx(), null, get_TrxName());
		batch2.setClientOrg(p_AD_Client_ID, p_AD_Org_ID);
		batch2.setDocumentNo(documentNo);
		batch2.setDescription(batch.getDocumentNo());
		batch2.setPostingType(X_A_Depreciation_Build.POSTINGTYPE_Actual);
		batch2.setGL_Category_ID(batch.getGL_Category_ID());
		batch2.setDateDoc(batch.getDateDoc());
		batch2.setDateAcct(batch.getDateAcct());
		batch2.setC_Period_ID(batch.getC_Period_ID());
		batch2.setC_Currency_ID(batch.getC_Currency_ID());
		batch2.setControlAmt(BigDecimal.valueOf(0));
		batch2.setC_DocType_ID(batch.getC_DocType_ID());
		batch2.setProcessing(true);
		batch2.setProcessed(true);
		
		batch2.setDocStatus(MJournalBatch.STATUS_InProgress);
		batch2.setDocAction(MJournalBatch.ACTION_Prepare);
		if (!batch2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +batch2.getDocumentNo());
		} 
		
		batch.setDescription(documentNo);
		
		MJournal journal = new MJournal(batch2);
		
		journal.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal.setIsActive(true);
		journal.setC_AcctSchema_ID(1000000);
		journal.setC_DocType_ID(batch.getC_DocType_ID());
		journal.setDocumentNo(batch.getDocumentNo() + "1");
		journal.setDocStatus(batch.getDocStatus());
		journal.setDocAction("--");
		journal.setIsApproved(true);
		journal.setIsPrinted(false);
		journal.setDescription(batch.getDescription());
		journal.setPostingType(batch.getPostingType());
		journal.setGL_Category_ID(batch.getGL_Category_ID());
		journal.setDateDoc(batch.getDateDoc());
		journal.setDateAcct(batch.getDateAcct());
		journal.setC_Period_ID(batch.getC_Period_ID());
		journal.setCurrencyRate(new BigDecimal(1));
		journal.setControlAmt(new BigDecimal(0));
		journal.setC_ConversionType_ID(114);
		journal.setProcessing(true);
		journal.setProcessed(true);
		journal.setPosted(true);
		
		MJournal journal2 = new MJournal(batch2);
		
		journal2.setClientOrg(getAD_Client_ID(), p_AD_Org_ID);
		journal2.setIsActive(true);
		journal2.setC_AcctSchema_ID(1000000);
		journal2.setC_DocType_ID(batch.getC_DocType_ID());
		journal2.setDocumentNo(batch.getDocumentNo() + "2");
		journal2.setDocStatus(batch.getDocStatus());
		journal2.setDocAction("--");
		journal2.setIsApproved(true);
		journal2.setIsPrinted(false);
		journal2.setDescription(batch.getDescription() + "2");
		journal2.setPostingType(batch.getPostingType());
		journal2.setGL_Category_ID(batch.getGL_Category_ID());
		journal2.setDateDoc(batch.getDateDoc());
		journal2.setDateAcct(batch.getDateAcct());
		journal2.setC_Period_ID(batch.getC_Period_ID());
		journal2.setCurrencyRate(new BigDecimal(1));
		journal2.setControlAmt(new BigDecimal(0));
		journal2.setC_ConversionType_ID(114);
		journal2.setProcessing(true);
		journal2.setProcessed(true);
		journal2.setPosted(true);
		
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		} 
		
		if (!journal2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal2.getDocumentNo());
		} 
		
		StringBuffer sql = new StringBuffer();
		
		for (MJournalLine line : lines) 
		{			
			MJournalLine newLine = new MJournalLine(journal);
								
			newLine.setAD_Org_ID(p_AD_Org_ID);
			newLine.setIsActive(true);
			newLine.setLine(100);
			newLine.setCurrency(341, 114, new BigDecimal(1));
			newLine.setDateAcct(journals[0].getDateAcct());
			newLine.setC_ValidCombination_ID(line.getC_ValidCombination_ID());
			newLine.setProcessed(true);
			newLine.setA_CreateAsset(false);
			newLine.setA_Processed(false);
			
			newLine.setAmtAcctCr(line.getAmtAcctCr().negate());
			newLine.setAmtAcctDr(line.getAmtAcctDr().negate());			
			newLine.setAmtSourceCr(line.getAmtSourceCr().negate());
			newLine.setAmtSourceDr(line.getAmtSourceDr().negate());
			
			newLine.save();
			
			sql.setLength(0);
			sql.append("select v.account_id from gl_journalline l " + 
					   "inner join c_validcombination v on l.c_validcombination_id = v.c_validcombination_id " +
					   "where gl_journalline_id = " + line.get_ID());
			int accountID = DB.getSQLValue(get_TrxName(), sql.toString());
			if (accountID<0) return "Error C_ElementValue_ID2";
			
			MFactAcct acct = new MFactAcct(getCtx(), null, get_TrxName());
			acct.setAmtAcctCr(line.getAmtAcctCr().negate());
			acct.setAmtAcctDr(line.getAmtAcctDr().negate());					
			acct.setAmtSourceCr(line.getAmtSourceCr().negate());
			acct.setAmtSourceDr(line.getAmtSourceDr().negate());
			acct.setAccount_ID(line.getAmtAcctCr().doubleValue()  == 0 ? accountID : accountID2);
			acct.setC_AcctSchema_ID(1000000);
			acct.setC_Period_ID(c_period_id);
			acct.setAD_Table_ID(224);
			acct.setRecord_ID(journal.get_ID());
			acct.setGL_Category_ID(journal.getGL_Category_ID());
			acct.setC_Currency_ID(journal.getC_Currency_ID());
			acct.setDateAcct(journal.getDateAcct());
			acct.setDateTrx(journal.getDateAcct());
			acct.setPostingType("A");
			acct.save();
		}
		
		MJournalLine[] lines2 = journals[1].getLines(true);
		
		for (MJournalLine line : lines2) 
		{			
			MJournalLine newLine = new MJournalLine(journal2);
								
			newLine.setAD_Org_ID(p_AD_Org_ID);
			newLine.setIsActive(true);
			newLine.setLine(100);
			newLine.setCurrency(341, 114, new BigDecimal(1));
			newLine.setDateAcct(journals[1].getDateAcct());
			newLine.setC_ValidCombination_ID(line.getC_ValidCombination_ID());
			newLine.setProcessed(true);
			newLine.setA_CreateAsset(false);
			newLine.setA_Processed(false);
			
			newLine.setAmtAcctCr(line.getAmtAcctCr().negate());
			newLine.setAmtAcctDr(line.getAmtAcctDr().negate());			
			newLine.setAmtSourceCr(line.getAmtSourceCr().negate());
			newLine.setAmtSourceDr(line.getAmtSourceDr().negate());
			
			newLine.save();
			
			sql.setLength(0);
			sql.append("select v.account_id from gl_journalline l " + 
					   "inner join c_validcombination v on l.c_validcombination_id = v.c_validcombination_id " +
					   "where gl_journalline_id = " + line.get_ID());
			int accountID = DB.getSQLValue(get_TrxName(), sql.toString());
			if (accountID<0) return "Error C_ElementValue_ID2";
			
			MFactAcct acct = new MFactAcct(getCtx(), null, get_TrxName());
			acct.setAmtAcctCr(line.getAmtAcctCr().negate());
			acct.setAmtAcctDr(line.getAmtAcctDr().negate());					
			acct.setAmtSourceCr(line.getAmtSourceCr().negate());
			acct.setAmtSourceDr(line.getAmtSourceDr().negate());
			
			//Set GL_Catecory_ID
			/*StringBuffer sql = new StringBuffer();
			sql.setLength(0);
			sql.append("SELECT c_validcombination_id FROM c_validcombination "
			+ " WHERE isActive='Y' AND account_id = " + acct.getAccount_ID() + clientCheck);
			int validation1 = DB.getSQLValue(get_TrxName(), sql.toString());
			if (validation1<0) return "Error C_ValidCombination_ID";
			*/
			acct.setAccount_ID(line.getAmtAcctCr().doubleValue()  == 0 ? accountID2 : accountID);
			acct.setC_AcctSchema_ID(1000000);
			acct.setC_Period_ID(c_period_id);
			acct.setAD_Table_ID(224);
			acct.setRecord_ID(journal2.get_ID());
			acct.setGL_Category_ID(1000003);
			acct.setC_Currency_ID(341);
			acct.setDateAcct(journal2.getDateAcct());
			acct.setDateTrx(journal2.getDateAcct());
			acct.setPostingType("A");
			acct.save();
		}
		
		boolean isSuccess = false;
		
		documentNo = "";
		
		journal.setTotalCr(journals[0].getTotalCr().negate());
		journal.setTotalDr(journals[0].getTotalDr().negate());

		journal2.setTotalCr(journals[1].getTotalCr().negate());
		journal2.setTotalDr(journals[1].getTotalDr().negate());
		
		batch2.setTotalCr(batch.getTotalCr().negate());
		batch2.setTotalDr(batch.getTotalDr().negate());
		
		journals[0].setDocStatus(MJournalBatch.STATUS_Voided);
		journals[1].setDocStatus(MJournalBatch.STATUS_Voided);
		journal.setDocStatus(MJournalBatch.STATUS_Reversed);
		journal2.setDocStatus(MJournalBatch.STATUS_Reversed);
		batch.setDocStatus(MJournalBatch.STATUS_Voided);
		batch2.setDocStatus(MJournalBatch.STATUS_Reversed);
		
		journals[0].setDocAction(MJournalBatch.ACTION_Reject);
		journals[1].setDocAction(MJournalBatch.ACTION_Reject);
		journal.setDocAction(MJournalBatch.ACTION_Reject);
		journal2.setDocAction(MJournalBatch.ACTION_Reject);
		batch.setDocAction(MJournalBatch.ACTION_Reject);
		batch2.setDocAction(MJournalBatch.ACTION_Reject);
		
		if (!batch2.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch2.getDocumentNo());
		} 
		if (!batch.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo());
		} 
		if (!journals[0].save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journals[0].getDocumentNo());
		} 
		if (!journals[1].save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journals[1].getDocumentNo());
		} 
		if (!journal.save()) {
			Log.log(Level.SEVERE, "Journal not saved - "+batch.getDocumentNo()+ " " +journal.getDocumentNo());
		} 
		if (!journal2.save()) {
			Log.log(Level.SEVERE, "Journal2 not saved - "+batch.getDocumentNo()+ " " +journal2.getDocumentNo());
		} 
		return "";
	}
	
/*
 * Add Ibraev E.A.
 * Created 21.09.2012
 * 
 * IEA {		
 */
		
	private Boolean CFPCloseMonth(int C_Period_ID) {
		Boolean result = true;
		if ( IsHaveCFP(C_Period_ID) && CFPBatchID(C_Period_ID) < 1) {
			result = false;
		}
		return result;
	}
	
	private Boolean IsHaveCFP(int C_Period_ID) {
		Boolean result = false;
		List<MPrepaidExpenses> FI_PrepaidExpenses = new ArrayList<MPrepaidExpenses>();
	    PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			String query = getCFPSql(C_Period_ID);
			pstmt = DB.prepareStatement(query,null);
			rs = pstmt.executeQuery();	
			while(rs.next()) {
				MPrepaidExpenses current = new MPrepaidExpenses(getCtx(),rs,null);
				if ( haveC_Invoice(current)) { 
					FI_PrepaidExpenses.add(current);
				}
			}
		} 
		catch (SQLException e) {
			log.log(Level.SEVERE, "product", e);
			return false;
		} 
		finally {
			DB.close(rs, pstmt);
			rs = null; pstmt = null;
		}	
		
		if (FI_PrepaidExpenses.size() > 0) {
			result = true;
		}
		return result;
	}

	protected MPeriod getPeriod(int C_Period_ID) {
		MPeriod period = new MPeriod(getCtx(), C_Period_ID, null);
		return period;
	}
	

	private String getCFPSql(int C_Period_ID) {
		String result = null;
		Timestamp BeginPeriod = getPeriod(C_Period_ID).getStartDate();
		Timestamp EndPeriod = getPeriod(C_Period_ID).getEndDate();
		result = "SELECT * FROM FI_PrepaidExpenses WHERE IsActive='Y' and (DocStatus = '"+MPrepaidExpenses.DOCSTATUS_Completed+"' or DocStatus = '"+MPrepaidExpenses.DOCSTATUS_InProgress+"') and posted='Y' and datefrom <= '" + EndPeriod.toString() + "' and '" + BeginPeriod.toString() + "' <= dateto"; 
//				"SELECT * FROM FI_PrepaidExpenses WHERE datefrom <= '" + EndPeriod.toString() + "' and '" + BeginPeriod.toString() + "' <= dateto";
		return result;
	}
	
	
	private int CFPBatchID(int C_Period_ID) {
		int result = 0;
		StringBuffer sql = new StringBuffer();
		String clientCheck = " AND AD_Client_ID=" + getAD_Client_ID();
		
		sql.setLength(0);
        sql.append("SELECT C_DocType_ID FROM C_DocType"
		+ " WHERE Name='Prepaid Expenses' AND isActive ='Y'"+clientCheck);        
        int C_DocType_ID = DB.getSQLValue(get_TrxName(), sql.toString());
		
		sql.setLength(0);		
		sql.append("SELECT GL_JournalBatch_ID FROM ADEMPIERE.GL_JournalBatch WHERE DOCSTATUS = 'CO' AND C_PERIOD_ID = " + String.valueOf(C_Period_ID)
				+ " AND C_DOCTYPE_ID = " + C_DocType_ID);
		result = DB.getSQLValue(get_TrxName(), sql.toString());
		return result;
	}

	private Boolean haveC_Invoice(MPrepaidExpenses current) {
		Boolean result = false;
		if (current.getC_InvoiceLine() != null) {
			result = true;
		}
		return result;
	}
	
/*
 * } IEA	
 */
}
